package com.jdjc.suject.domin.service.impl;


import com.alibaba.fastjson.JSON;
import com.jdjc.subject.common.entity.PageResult;
import com.jdjc.subject.common.enums.IsDeletedFlagEnum;
import com.jdjc.subject.common.enums.SubjectLikedStatusTypeEnum;
import com.jdjc.subject.common.util.LoginUtil;
import com.jdjc.subject.infra.basic.entity.SubjectInfo;
import com.jdjc.subject.infra.basic.entity.SubjectLiked;
import com.jdjc.subject.infra.basic.service.SubjectInfoService;
import com.jdjc.subject.infra.basic.service.SubjectLikedService;
import com.jdjc.suject.domin.convert.SubjectInfoConverter;
import com.jdjc.suject.domin.convert.SubjectLikedConverter;
import com.jdjc.suject.domin.entity.SubjectInfoBO;
import com.jdjc.suject.domin.entity.SubjectLikedBO;
import com.jdjc.suject.domin.redis.RedisUtil;
import com.jdjc.suject.domin.service.SubjectLikedDomainService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;


@Service
@Slf4j
public class SubjectLikedDomainServiceImpl implements SubjectLikedDomainService {
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private SubjectLikedService subjectLikedService;
    @Resource
    private SubjectInfoService subjectInfoService;


    //总的hashkey
    private static final String SUBJECT_LIKED_KEY = "subject.liked";
    //总的点赞数的key
    private static final String SUBJECT_LIKED_COUNT_KEY = "subject.liked.count";

    //被谁点过赞的key
    private static final String SUBJECT_LIKED_DETAIL_KEY = "subject.liked.detail";

    /**
     * 点赞
     *
     * @param subjectLikedBO
     * @return
     */
    @Override
    public void add(SubjectLikedBO subjectLikedBO) {
        Long subjectId = subjectLikedBO.getSubjectId();
        String likeUserId = subjectLikedBO.getCreatedBy();
        Integer status = subjectLikedBO.getStatus();
        //生成hashKey
        String hashKey = buildSubjectLikedKey(subjectId.toString(), likeUserId);
        //存入reids缓存subject.liked.subjectId:loginId:"status"
        redisUtil.putHash(SUBJECT_LIKED_KEY, hashKey, status);
        //用于记录是谁点赞
        String detailKey = SUBJECT_LIKED_DETAIL_KEY + "." + subjectId + "." + likeUserId;

        String countKey = SUBJECT_LIKED_COUNT_KEY + "." + subjectId;
        //是点赞，则计数器加一,并记录是谁点赞
        if (SubjectLikedStatusTypeEnum.LIKED.getCode() == status) {
            redisUtil.increment(countKey, 1);
            redisUtil.set(detailKey, "1");
        } else {
            //如果不是点赞则计数器-1，移除点赞用户
            Integer count = redisUtil.getInt(countKey);
            if (Objects.isNull(count) || count <= 0) {
                return;
            }
            redisUtil.increment(countKey, -1);
            redisUtil.del(detailKey);
        }
    }

    /**
     * 获取题目是否被当前用户点赞
     *
     * @param subjectId
     * @param userId
     * @return
     */
    @Override
    public Boolean isLiked(String subjectId, String userId) {
        //用于记录是谁点赞
        String detailKey = SUBJECT_LIKED_DETAIL_KEY + "." + subjectId + "." + userId;
        //key存在则被当前用户点赞
        return redisUtil.exist(detailKey);
    }

    /**
     * 获取题目点赞数量
     *
     * @param subjectId
     * @return
     */
    @Override
    public Integer getLikedCount(String subjectId) {
        String countKey = SUBJECT_LIKED_COUNT_KEY + "." + subjectId;
        Integer count = redisUtil.getInt(countKey);
        if (Objects.isNull(count) || count <= 0) {
            return 0;
        }

        return count;
    }

    /**
     * 同步点赞数据到数据库
     */
    @Override
    public void syncLiked() {
        //从redis缓存中获取所有点赞数据
        Map<Object, Object> subjectLikedMap = redisUtil.getHashAndDelete(SUBJECT_LIKED_KEY);
        log.info("syncLiked:subjectLikedMap:{}", JSON.toJSONString(subjectLikedMap));
        if (MapUtils.isEmpty(subjectLikedMap)) {
            return;
        }
        //批量同步到数据库
        List<SubjectLiked> subjectLikedList = new LinkedList<>();
        subjectLikedMap.forEach((key, value) -> {
            //key的形式100:o0kIv6148gj9CfZuHbkFiRqLLDTQ（subjectId:loginId)
            String keyString = key.toString();
            String[] keyArr = keyString.split(":");

            SubjectLiked subjectLiked = new SubjectLiked();
            subjectLiked.setSubjectId(Long.valueOf(keyArr[0]));
            subjectLiked.setLikeUserId(keyArr[1]);
            subjectLiked.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
            subjectLiked.setStatus((Integer) value);

            subjectLikedList.add(subjectLiked);

        });
        subjectLikedService.batchInsert(subjectLikedList);
    }

    /**
     * 获取点赞列表
     *
     * @param subjectLikedBO
     * @return
     */
    @Override
    public PageResult<SubjectLikedBO> getSubjectLikedPage(SubjectLikedBO subjectLikedBO) {
        PageResult<SubjectLikedBO> pageResult = new PageResult<>();
        pageResult.setPageNo(subjectLikedBO.getPageNo());
        pageResult.setPageSize(subjectLikedBO.getPageSize());
        int start = (subjectLikedBO.getPageNo() - 1) * subjectLikedBO.getPageSize();

        SubjectLiked subjectLiked = SubjectLikedConverter.INSTANCE.convertBOToLiked(subjectLikedBO);
        subjectLiked.setLikeUserId(LoginUtil.getLoginId());
        //获取总条数
        int count = subjectLikedService.countByCondition(subjectLiked);
        if (count == 0) {
            return pageResult;
        }
        //分页查询点赞列表
        List<SubjectLiked> subjectLikedList = subjectLikedService.queryPage(subjectLiked, start, subjectLikedBO.getPageSize());

        List<SubjectLikedBO> subjectLikedBOList = SubjectLikedConverter.INSTANCE.likedListToBOList(subjectLikedList);
        subjectLikedBOList.forEach(likedBO -> {
            //获取点赞的题目信息
            SubjectInfo subjectInfo = subjectInfoService.queryById(likedBO.getSubjectId());
            likedBO.setSubjectName(subjectInfo.getSubjectName());
        });
        pageResult.setRecords(subjectLikedBOList);
        pageResult.setTotal(count);
        return pageResult;
    }

    /**
     * 拼接生成hashKey
     *
     * @param subjectId
     * @param userId
     * @return
     */
    private String buildSubjectLikedKey(String subjectId, String userId) {
        return subjectId + ":" + userId;
    }
}
